package com.token.base;

import java.io.PrintWriter;
import java.util.Vector;
import java.util.Date;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lotus.domino.Document;
import lotus.domino.NotesException;

/**
 * 基类，处理当前会话、URL参数、Ajax输出类型等。
 *
 * @author chenjianxiong 2020/2/15
 */
public abstract class BaseUtil {
    private String[][] queryKey = null;
    private JSONObject jsonData;

    private Date startDate = null;

    public Date initStartTime() {
        startDate = new Date();
        return startDate;
    }

    public void printRunTime(Date start, String title) {
        Date date2 = new Date();
        System.out.println("--->" + title + "程序运行时间【" + (date2.getTime() - start.getTime()) + "毫秒】");
        startDate = new Date();
    }

    public void printRunTime(String title) {
        this.printRunTime(startDate, title);
    }

    /**
     * 获取输出JSON
     *
     * @return JSONObject
     */
    public JSONObject getJsonData() {
        return jsonData;
    }

    /**
     * 设置JSON输出对象
     *
     * @param json JSON对象
     */
    public void setJsonData(JSONObject json) {
        jsonData = json;
    }

    /**
     * 获取传入参数数组
     *
     * @return String[][]
     */
    public String[][] getQueryKey() {
        return queryKey;
    }

    /**
     * 构造函数，生成当前会话，数据库，文档对象。
     *
     * @throws NotesException 错误信息
     */
    public BaseUtil() throws NotesException {
        this.jsonData = new JSONObject();
        this.putSuccess();
    }

    /**
     * 写入JSON元素
     *
     * @param key   名称
     * @param value Object值
     */
    public void putJsonData(String key, Object value) {
        jsonData.put(key, value);
    }

    /**
     * 写入JSON元素
     *
     * @param key   名称
     * @param value 字符串
     */
    public void putJsonData(String key, String value) {
        jsonData.put(key, value);
    }

    /**
     * 写入JSON元素
     *
     * @param key   名称
     * @param value int数值
     */
    public void putJsonData(String key, int value) {
        jsonData.put(key, value);
    }

    /**
     * 写入JSON元素
     *
     * @param key   名称
     * @param value double数值
     */
    public void putJsonData(String key, double value) {
        jsonData.put(key, value);
    }

    /**
     * 写入JSON元素
     *
     * @param key   名称
     * @param value long数值
     */
    public void putJsonData(String key, long value) {
        jsonData.put(key, value);
    }

    /**
     * 写入JSON元素
     *
     * @param key   名称
     * @param value true or false
     */
    public void putJsonData(String key, boolean value) {
        jsonData.put(key, value);
    }

    /**
     * 写入JSON元素
     *
     * @param key   名称
     * @param value JSON对象
     */
    public void putJsonData(String key, JSONObject value) {
        jsonData.put(key, value);
    }

    /**
     * 写入JSON元素
     *
     * @param key   名称
     * @param value JSON数组
     */
    public void putJsonData(String key, JSONArray value) {
        jsonData.put(key, value);
    }

    /**
     * 写入成功JSON
     *
     * @param message 成功描述
     */
    public void putSuccess(String message) {
        jsonData.put("code", 0);
        jsonData.put("message", message);
    }

    /**
     * 写入成功JSON
     */
    public void putSuccess() {
        this.putSuccess("操作成功");
    }

    /**
     * 输出所有参数到控制台
     */
    public void printQv() {
        initQueryKey();
        if (queryKey == null) {
            return;
        }
        int length = queryKey[0].length;
        if (length > 0) {
            for (int i = 0; i < length; i++) {
                System.out.println(queryKey[0][i] + " = " + queryKey[1][i]);
            }
        }
    }

    /**
     * URL参数写入到文档对象
     *
     * @param doc 文档对象
     * @throws NotesException 错误信息
     */
    public void setQueryKeyToDoc(Document doc) throws NotesException {
        initQueryKey();
        if (queryKey == null) {
            return;
        }
        int length = queryKey[0].length;
        if (length > 0) {
            for (int i = 0; i < length; i++) {
                doc.replaceItemValue(queryKey[0][i], queryKey[1][i]);
            }
        }
    }

    /**
     * 处理前端传过来的参数<br>
     * String[0][0]="name"
     * String[0][1]="value"
     *
     * @return String[][]
     */
    protected abstract String[][] initQueryValue();

    /**
     * 根据key获取值
     *
     * @param key 参数名
     * @return String
     */
    public String getUrlQueryString(String key) {
        initQueryKey();
        if (queryKey == null) {
            return null;
        }
        int length = queryKey[0].length;
        if (length > 0) {
            for (int i = 0; i < length; i++) {
                if (queryKey[0][i].equals(key)) {
                    return queryKey[1][i];
                }
            }
        }
        return null;
    }

    /**
     * 判断必填，并且抛出异常。
     *
     * @param key    参数名
     * @param isNeed true 判断必填
     * @param tips   字段中文描述
     * @return String
     * @throws Exception 错误信息
     */
    public String getUrlQueryString(String key, boolean isNeed, String tips) throws Exception {
        initQueryKey();
        if (queryKey == null) {
            return null;
        }
        int length = queryKey[0].length;
        if (length > 0) {
            for (int i = 0; i < length; i++) {
                if (queryKey[0][i].equals(key)) {
                    if (isNeed) {
                        if ("".equals(queryKey[1][i])) {
                            throw new ToKenException("[" + tips + "]参数不能为空值！");
                        } else {
                            return queryKey[1][i];
                        }
                    } else {
                        return queryKey[1][i];
                    }

                }
            }
        }

        if (isNeed) {
            throw new ToKenException("[" + tips + "]参数不能为空值！");
        } else {
            return null;
        }
    }

    private void initQueryKey() {
        if (queryKey == null) {
            queryKey = this.initQueryValue();
        }
    }

    /**
     * 把多个相同参数合并成数组。
     *
     * @param key URLKey
     * @return Vector
     */
    public Vector<String> getUrlQueryVector(String key) {
        initQueryKey();
        if (queryKey == null) {
            return null;
        }

        Vector<String> ve = new Vector<String>();
        if (queryKey[0].length > 0) {
            for (int i = 0; i < queryKey[0].length; i++) {
                if (key.equals(queryKey[0][i])) {
                    ve.add(queryKey[1][i]);
                }
            }
        }
        return ve;
    }

    /**
     * 把多个相同参数合并成一个字符
     *
     * @param key URLKey
     * @param hb  合并字符，如：分号或逗号
     * @return String
     */
    public String getUrlQueryString(String key, String hb) {
        initQueryKey();
        if (queryKey == null) {
            return null;
        }
        StringBuilder stringBuilder = new StringBuilder(50);
        if (queryKey[0].length > 0) {
            boolean b = false;
            for (int i = 0; i < queryKey[0].length; i++) {
                if (key.equals(queryKey[0][i])) {
                    if (b) {
                        stringBuilder.append(hb);
                    } else {
                        b = true;
                    }
                    stringBuilder.append(queryKey[1][i]);
                }
            }
        }
        return stringBuilder.toString();
    }

    /**
     * 输出：application/json;charset=utf-8。
     *
     * @param getAgentOutput 输出对象
     */
    public void printJsonData(PrintWriter getAgentOutput) {
        this.printJsonData(getAgentOutput, this.jsonData.toString());
    }

    /**
     * 输出：application/json;charset=utf-8。
     *
     * @param getAgentOutput 输出对象
     * @param json           JSON对象
     */
    public void printJsonData(PrintWriter getAgentOutput, JSONObject json) {
        this.printJsonData(getAgentOutput, json.toString());
    }

    /**
     * 输出：application/json;charset=utf-8。
     *
     * @param getAgentOutput 输出对象
     * @param str            字符
     */
    private void printJsonData(PrintWriter getAgentOutput, String str) {
        getAgentOutput.println("Content-type:application/json;charset=utf-8");
        getAgentOutput.println(str);
        getAgentOutput.close();
    }

    /**
     * 输出：text/html;charset=utf-8。
     *
     * @param getAgentOutput 输出对象
     * @param str            字符
     */
    public void printHtmlData(PrintWriter getAgentOutput, String str) {
        getAgentOutput.println("Content-type:text/html;charset=utf-8");
        getAgentOutput.println(str);
        getAgentOutput.close();
    }

    /**
     * 输出：text/xml;charset=utf-8。
     *
     * @param getAgentOutput 输出对象
     * @param str            字符
     */
    public void printXmlData(PrintWriter getAgentOutput, String str) {
        getAgentOutput.println("Content-type:text/XML;charset=utf-8");
        getAgentOutput.println(str);
        getAgentOutput.close();
        //saveAPIData(str,"xml");
    }

    /**
     * 输出：text/plain;charset=utf-8。
     *
     * @param getAgentOutput 输出对象
     * @param str            字符
     */
    public void printTextData(PrintWriter getAgentOutput, String str) {
        getAgentOutput.println("Content-type:text/plain;charset=utf-8");
        getAgentOutput.println(str);
        getAgentOutput.close();
        //saveAPIData(str,"text");
    }


    /**
     * 输出成功的JSON数据。
     *
     * @param getAgentOutput 输出对象
     */
    public void printSuccessData(PrintWriter getAgentOutput) {
        this.putSuccess();
        this.printJsonData(getAgentOutput, jsonData);
    }

    /**
     * 输出错误信息的JSON数据
     *
     * @param getAgentOutput 输出对象
     * @param msgErr         错误信息
     */
    public void printWriteErr(PrintWriter getAgentOutput, String msgErr) {
        try {
            jsonData.put("code", 1);
            jsonData.put("message", msgErr);
            this.printJsonData(getAgentOutput, jsonData);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 错误地址。
     */
    protected abstract void printAgentName();

    /**
     * 输出错误。
     *
     * @param getAgentOutput 输出对象
     * @param e              错误信息
     */
    public void printWriteErr(PrintWriter getAgentOutput, Exception e) {
        try {
            printAgentName();
            String msg = e.getMessage();
            if (msg == null || "".equals(msg)) {
                msg = e.toString();
            }
            this.printWriteErr(getAgentOutput, msg);
        } catch (Exception e1) {
            this.printWriteErr(getAgentOutput, e.toString());
            e1.printStackTrace();
        }
    }

    /**
     * 释放当前使用的Domino类。
     */
    public abstract void recycle();
}

